package com.ruoyi.system.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ruoyi.common.constant.WorkFlowConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.Threads;
import com.ruoyi.system.domain.ProcessTemplates;
import com.ruoyi.system.domain.dto.HandleDataDTO;
import com.ruoyi.system.domain.vo.HandleDataVO;
import com.ruoyi.system.domain.vo.TaskDetailVO;
import com.ruoyi.system.service.IProcessTemplatesService;
import com.ruoyi.system.service.WorkspaceProcessService;
import lombok.extern.log4j.Log4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.ApproveTimeoutStatisticMapper;
import com.ruoyi.system.domain.ApproveTimeoutStatistic;
import com.ruoyi.system.service.IApproveTimeoutStatisticService;

import javax.annotation.Resource;

/**
 * 审批超时Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-12
 */
@Service
public class ApproveTimeoutStatisticServiceImpl implements IApproveTimeoutStatisticService
{
    private static final Logger logger = LoggerFactory.getLogger(ApproveTimeoutStatisticServiceImpl.class);

    @Autowired
    private ApproveTimeoutStatisticMapper approveTimeoutStatisticMapper;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private IProcessTemplatesService processTemplateService;
    @Autowired
    private WorkspaceProcessService workspaceProcessService;

    /**
     * 查询审批超时
     *
     * @param processInstanceIdList 流程实例ID
     * @return 审批超时
     */
    @Override
    public  List<HandleDataVO> selectApproveTimeoutStatisticById(List<String> processInstanceIdList)
    {
        List<HandleDataVO> resultList = new ArrayList<>();
        for(String processInstanceId : processInstanceIdList){
            HandleDataDTO handleDataDTO = new HandleDataDTO();
            handleDataDTO.setProcessInstanceId(processInstanceId);
            HandleDataVO record = workspaceProcessService.instanceInfo(handleDataDTO);
            resultList.add(record);
        }
        return resultList;
    }

    /**
     * 查询审批超时统计列表数据
     *
     * @return 审批超时
     */
    @Override
    public List<ApproveTimeoutStatistic> selectApproveTimeoutStatisticList()
    {
        List<ApproveTimeoutStatistic> resultList = new ArrayList<>();
        //查询所有的流程
        List<HistoricProcessInstance> historicProcessInstances =
                historyService.createHistoricProcessInstanceQuery()
                        .includeProcessVariables()
                        .orderByProcessInstanceStartTime()
                        .desc()
                        .list();
        //筛选超时的流程
        List<ApproveTimeoutStatistic> approveTimeoutList = new ArrayList<>();
        for(HistoricProcessInstance historicProcessInstance : historicProcessInstances){
            long totalTimes = historicProcessInstance.getEndTime()==null?
                    (Calendar.getInstance().getTimeInMillis()-historicProcessInstance.getStartTime().getTime()):
                    (historicProcessInstance.getEndTime().getTime()-historicProcessInstance.getStartTime().getTime());
            String processDefinitionKey = historicProcessInstance.getProcessDefinitionKey();
            //查询到流程图设置的超时时间
            ProcessTemplates processTemplates = processTemplateService.selectProcessTemplatesByTemplateId(processDefinitionKey.replace(WorkFlowConstants.PROCESS_PREFIX,""));
            Long timeLimit = Long.valueOf(processTemplates.getTimeLimit());
            //判断是否超时，超时时间
            long balance = totalTimes - timeLimit * 1000 * 60 * 60;
            if(balance>0){
                ApproveTimeoutStatistic approveTimeout = new ApproveTimeoutStatistic();
                approveTimeout.setTemplateId(processTemplates.getTemplateId());
                approveTimeout.setTemplateName(processTemplates.getTemplateName());
                //TODO
                Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
                approveTimeout.setUserId(1L);
                approveTimeout.setUserName("");
                approveTimeout.setTimeOutTime(balance);
                approveTimeout.setProcessInstanceId(historicProcessInstance.getProcessDefinitionId());
                approveTimeoutList.add(approveTimeout);
            }
        }
        //根据人员、流程图模板组装数据
        Map<Long, Map<String, List<ApproveTimeoutStatistic>>> collect = approveTimeoutList.stream().collect(Collectors.groupingBy(ApproveTimeoutStatistic::getUserId, Collectors.groupingBy(ApproveTimeoutStatistic::getTemplateId)));
        for (Long userId : collect.keySet()) {
            logger.info("key = " + userId + ", value = " + collect.get(userId));
            Map<String, List<ApproveTimeoutStatistic>> stringListMap = collect.get(userId);
            for(String templateId : stringListMap.keySet()){
                ApproveTimeoutStatistic approveTimeoutStatistic = new ApproveTimeoutStatistic();
                approveTimeoutStatistic.setUserId(userId);
                approveTimeoutStatistic.setTemplateId(templateId);
                List<ApproveTimeoutStatistic> approveTimeoutStatistics = stringListMap.get(stringListMap);
                ApproveTimeoutStatistic approveData = approveTimeoutStatistics.get(0);
                approveTimeoutStatistic.setUserName(approveData.getUserName());
                approveTimeoutStatistic.setTemplateName(approveData.getTemplateName());
                approveTimeoutStatistic.setTimeoutMum(approveTimeoutStatistics.size());
                long count = approveTimeoutStatistics.stream().map(ApproveTimeoutStatistic::getTimeOutTime).count();
                approveTimeoutStatistic.setTimeoutTotal(count);
                List<String> processInstanceIdList = approveTimeoutStatistics.stream().map(ApproveTimeoutStatistic::getProcessInstanceId).collect(Collectors.toList());
                approveTimeoutStatistic.setProcessInstanceIdList(processInstanceIdList);
                resultList.add(approveTimeoutStatistic);
            }
        }
        return resultList;
    }

}
